/*
* yasl-qt (or simply yasl) is a qt-based program for symbian devices
* and intended to manage a shopping list.
* The acronym yasl stands for Yet Another Shopping List.
* 
* Copyright (C) 2011 - Alessandro Orlandi
* 
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "SearchableListView.h"
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>

SearchableListView::SearchableListView(QWidget *parent) :
    QListView(parent)
{
    //call init()
    init();

}

bool SearchableListView::init()   {

//set the filtered model...
mModel = new QStringListModel(this);

mFilterProxy = new QSortFilterProxyModel(this);
mFilterProxy->setSourceModel(mModel); // Set model as source model to the proxy

mFilterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
setModel(mFilterProxy); // set the filtered model as data source

loadHistoryFile();
updateDataModel();
return true;


}

bool SearchableListView::loadHistoryFile()
{
    //load data from file
    QDir dir = QDir::root();
    bool lDirExists = true;
    if (!dir.cd("Data/ShoppingList"))
    {
        qWarning("Cannot find the \"/Data\" directory");
        return false;
    }

    if (lDirExists)
    {
        dir.cd("Data/ShoppingList");
        QFile file(dir.filePath("history.txt"));
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qWarning("Can't open file");
            return false;
        }

        while (!file.atEnd())
        {
            QByteArray line = file.readLine();
            QString lItemName(line);
            mData << lItemName.replace("\n","");
        }

        return true;

    }
    else
    {
        return false;
    }
}

bool SearchableListView::updateDataModel()
{

    mModel->setStringList(mData);
    return true;
}

//receive a list of items and add to history list the ones not already present
void  SearchableListView::addItemsToHistory(QStringList pItemsStringList)
{


    for (int i = 0; i< pItemsStringList.length(); i++)
    {
        QString lCurrentItemName = pItemsStringList.at(i);
        if (!mData.contains(lCurrentItemName, Qt::CaseInsensitive))
        {
            mData << lCurrentItemName;
        }
    }
    mData.sort();
    mModel->setStringList(mData); // Fill model with data
    saveHistory();



}

bool SearchableListView::saveHistory()
{

    QDir dir = QDir::root();
    bool lDirExists = true;
    if (!dir.cd("Data/ShoppingList"))
    {

        qWarning("Cannot find the \"/Data\" directory");
        lDirExists = dir.mkpath("Data/ShoppingList");
    }

    if (lDirExists)
    {
        dir.cd("Data/ShoppingList");
        QFile file(dir.filePath("history.txt"));
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            //qWarning("Can't create file");
            return false;
        }

        QTextStream lOut(&file);
        for (int i=0; i < mData.length() ; i++)
        {
            lOut << mData.at(i) << "\n";
        }
    }
    return true;
}

bool SearchableListView::addSelectedItemToShoppingList()
{


    QModelIndexList lSelectedItemsIndexes = selectedIndexes();    


    if (lSelectedItemsIndexes.length()>0)
    {

        // WARN: this mechanism WON'T WORK when history list is filtered
        // because it returns the item at index #i of the *complete* list (hidden and shown items)
        // and not the one with index #i of the *displayed* list
        // In the application it works fine *beacuse* once an item has been selected,
        // *all* items are shown (and in this case, the index of the selected item matches the ndex of mData entry)
        QString lItemName = mData.at(lSelectedItemsIndexes.at(0).row());
        if (lItemName != NULL )
        {
            QMessageBox lConfirmationMsgBox;
            lConfirmationMsgBox.setText("Item added!");
            lConfirmationMsgBox.setInformativeText("Item " + lItemName + " has been added to shopping list.");
            lConfirmationMsgBox.setStandardButtons(QMessageBox::Ok);
            lConfirmationMsgBox.setDefaultButton(QMessageBox::Ok);
            lConfirmationMsgBox.show();
            lConfirmationMsgBox.exec();


            emit sigBuyItem(lItemName);
            return true;
        }
    }
    return false;

}

bool SearchableListView::deleteSelectedItem()
{
    QModelIndexList lSelectedItemsIndexes = selectedIndexes();
    if (lSelectedItemsIndexes.length()>0)
    {
        QMessageBox lConfirmationMsgBox;
        lConfirmationMsgBox.setText("Removing item!");
        lConfirmationMsgBox.setInformativeText("Selected item will be permanently removed from history.\nAre you sure?");
        lConfirmationMsgBox.setStandardButtons(QMessageBox::No|QMessageBox::Yes);
        lConfirmationMsgBox.setDefaultButton(QMessageBox::No);
        lConfirmationMsgBox.show();
        int lActionConfirmed = lConfirmationMsgBox.exec();


        QString lItemName = mData.at(lSelectedItemsIndexes.at(0).row());
        if (lItemName != NULL && lActionConfirmed == QMessageBox::Yes)
        {
            if (mData.removeOne(lItemName))
            {
                updateDataModel();
                saveHistory();
            }
        }
    }
    return true;
}

bool SearchableListView::updateFilter(QString pNewFilterText)
{
  mFilterProxy->setFilterFixedString(pNewFilterText);
  QStringList lMatchingData;
  for (int i=0; i < mData.length(); i++)
  {
      if ( mData.at(i).contains(pNewFilterText,Qt::CaseInsensitive) )
      {
          lMatchingData.append(mData.at(i));
      }
  }
  emit sigListUpdated(lMatchingData, pNewFilterText);
  return true;

}


